package com.lcf.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ChenFei
 */
public class TreeUtils {

    private static final String[] KEY_ARR = {"id","parentId","name","order"};

    private static final String DATA_MAP = "dataMap";

    private static final int DEEP = 5;

    //自定义默认配置
    private static final TreeNodeConfig TREE_NODE_CONFIG = new TreeNodeConfig()
            .setWeightKey(KEY_ARR[3])
            .setIdKey(KEY_ARR[0])
            .setNameKey(KEY_ARR[2])
            .setParentIdKey(KEY_ARR[1])
            // 最大递归深度
            .setDeep(DEEP);

    public static List<Tree<String>> toTree(List<?> dataList){
        return toTree(dataList,"0",null);
    }

    public static List<Tree<String>> toTree(List<Object> dataList,String rootId){
        return toTree(dataList,rootId,null);
    }

    /**
     * list转为tree
     * @param dataList
     * @param rootId
     * @return
     */
    public static List<Tree<String>> toTree(List<?> dataList,String rootId,TreeNodeConfig treeNodeConfig){
        final TreeNodeConfig config = treeNodeConfig == null ? TREE_NODE_CONFIG : treeNodeConfig;
        //https://www.hutool.cn/docs/#/core/%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7/%E6%A0%91%E7%BB%93%E6%9E%84/%E6%A0%91%E7%BB%93%E6%9E%84%E5%B7%A5%E5%85%B7-TreeUtil
        List<TreeNode<String>> nodeList = CollUtil.newArrayList();
        dataList.forEach(data -> {
            //对象转为map
            Map<String, Object> map = BeanUtil.beanToMap(data);
            TreeNode<String> treeNode = new TreeNode<>();
            treeNode.setId(String.valueOf(map.get(config.getIdKey())));
            treeNode.setParentId(String.valueOf(map.get(config.getParentIdKey())));
            treeNode.setName(String.valueOf(map.get(config.getNameKey())));
            treeNode.setWeight(String.valueOf(map.get(config.getWeightKey())));
            //添加其他属性
            HashMap<String, Object> fieldMap = new HashMap<>();
            map.forEach((k,v)->{
                if (!Arrays.asList(KEY_ARR).contains(k)){
                    fieldMap.put(k,v);
                }
            });
            HashMap<String, Object> dataMap = new HashMap<>();
            dataMap.put(DATA_MAP, fieldMap);
            treeNode.setExtra(dataMap);
            nodeList.add(treeNode);
        });
        //list转为tree
        return TreeUtil.build(nodeList, rootId, config,
                (node, tree) -> {
                    tree.setId(node.getId());
                    tree.setParentId(node.getParentId());
                    tree.setWeight(node.getWeight());
                    tree.setName(node.getName());
                    // 扩展属性 ...
                    //tree.putExtra("extraField", 666);
                    //tree.putExtra("other", new Object());
                    Map<String, Object> nodeExtra = node.getExtra();
                    nodeExtra = BeanUtil.beanToMap(nodeExtra.get(DATA_MAP));
                    nodeExtra.forEach((k, v) -> {
                        tree.putExtra(k, v);
                    });

                });
    }
}
